package com.wjk.kylin.modules.system.role.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wjk.kylin.core.exception.BusinessException;
import com.wjk.kylin.modules.system.role.entity.Role;
import com.wjk.kylin.modules.system.role.mapper.RoleMapper;
import com.wjk.kylin.modules.system.role.service.IRoleDeptService;
import com.wjk.kylin.modules.system.role.service.IRoleMenuService;
import com.wjk.kylin.modules.system.role.service.IRoleService;
import com.wjk.kylin.modules.system.user.entity.User;
import com.wjk.kylin.modules.system.user.service.IUserRoleService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author wangjkui
 * @since 2020-06-01
 */
@Service
@Transactional(readOnly = true)
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    @Autowired
    private IRoleMenuService roleMenuService;
    @Autowired
    private IRoleDeptService roleDeptService;
    @Autowired
    private IUserRoleService userRoleService;

    @Override
    public IPage<Role> findPage(Page<Role> page, Role role) {
        return baseMapper.findPage(page, role);
    }

    @Override
    @Transactional(readOnly = false)
    public boolean save(Role role) {
        //1.判断code是否已经存在
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper.eq("code", role.getCode());
        int count = this.count(wrapper);
        if (count > 0) {
            throw new BusinessException("角色编码已存在，请重新添加");
        }

        role.preInsert();

        //1.保存数据成功之后获取角色id
        boolean flag = super.save(role);

        //2.保存角色菜单关联表
        if (flag && role.getMenuIds() != null && role.getMenuIds().length > 0) {
            roleMenuService.save(role.getId(), Arrays.asList(role.getMenuIds()));
        }

        return flag;
    }

    @Override
    @Transactional(readOnly = false)
    public boolean update(Role role) {
        //1.判断code是否已经存在
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper.eq("code", role.getCode());
        wrapper.ne("id", role.getId());
        int count = this.count(wrapper);
        if (count > 0) {
            throw new BusinessException("角色编码已存在，请重新修改");
        }

        role.preUpdate();

        //1.保存数据成功之后获取角色id
        boolean flag = super.updateById(role);

        //2.保存角色菜单关联表
        if (flag) {
            //删除关联关系
            roleMenuService.deleteByRoleIds(Arrays.asList(role.getId()));
            //保存角色菜单关联表
            if (role.getMenuIds() != null && role.getMenuIds().length > 0) {
                roleMenuService.save(role.getId(), Arrays.asList(role.getMenuIds()));
            }

        }

        return flag;
    }

    @Override
    @Transactional(readOnly = false)
    public boolean deleteByIds(String[] roleIds) {
        List<String> list = Arrays.asList(roleIds);
        //1.删除角色菜单关联数据
        roleMenuService.deleteByRoleIds(list);
        //2.删除角色部门关联数据
        roleDeptService.deleteByRoleIds(list);
        //3.删除用户角色关联数据
        userRoleService.deleteByRoleIds(list);
        return super.removeByIds(list);
    }

    @Override
    public Set<String> findRolePermissionByUser(User user) {
        Set<String> roles = new HashSet<>();
        // 管理员拥有所有权限
        if (user.isAdmin()) {
            roles.add("admin");
        } else {
            List<Role> roleList = baseMapper.findRolePermissionByUserId(user.getId());
            roles.addAll(roleList.stream().map(Role::getCode).collect(Collectors.toSet()));
        }
        return roles;
    }

    @Override
    @Transactional(readOnly = false)
    public boolean authDataScope(Role role) {
        role.preUpdate();

        //1.保存数据成功之后获取角色id
        boolean flag = super.updateById(role);

        //2.保存角色部门关联表
        if (flag) {
            //删除关联关系
            roleDeptService.deleteByRoleIds(Arrays.asList(role.getId()));
            //保存角色菜单关联表
            if (role.getDeptIds() != null && role.getDeptIds().length > 0) {
                roleDeptService.save(role.getId(), Arrays.asList(role.getDeptIds()));
            }

        }

        return flag;
    }

    @Override
    @Transactional(readOnly = false)
    public boolean changeStatus(String roleId, String status) {
        Role role = super.getById(roleId);

        if (StringUtils.isNotBlank(status) && !status.equals(role.getStatus())) {
            role.setStatus(status);
            role.preUpdate();

            return super.updateById(role);
        }

        return false;
    }

}
